import { Request } from "express";
import literature from "@src/models/literature";
import moment from "moment";
import { clone, getID } from "@src/util/util";
import Constant from "@src/util/constant";
import file from "@src/models/file";
import { Op } from "sequelize";
import File from "@src/models/file";
import Dict from "@src/models/dict";
import dictSql from "@src/sql/dictSql";

// 文献附件和图片是否存在
const isFileId = async (id: string) => {
  return await file.findOne({
    where: {
      id,
    },
  });
};

// 查询是否存在该文献
const isLiterature = async (id: string) => {
  return await literature.findOne({
    where: {
      id,
    },
  });
};

// 查询名字是否重复
const isLiteratureName = async (name: string) => {
  return await literature.findOne({
    where: {
      name,
    },
  });
};

// 添加文献
const add = async (req: Request) => {
  // 是否存在该分类
  let resObj = clone(Constant.ADD_DEFAULT_SUCCESS);
  await literature.create({
    ...req.body,
    id: getID(),
    created_at: moment().format("X"),
    recommend: 0,
    grounding: 0,
    visit_num: 0,
  });
  return resObj;
};

// 删除文献
const _delete = async (id: string) => {
  // 是否存在该文献
  if (!(await isLiterature(id))) {
    return Constant.LITERATURE_NOT_ERROR;
  }
  await literature.destroy({
    where: {
      id,
    },
  });
  return Constant.DEFAULT_SUCCESS;
};

// 更新文献
const update = async (req: Request) => {
  const { id } = req.params;
  return await literature.update({
    ...req.body,
    updated_at: moment().format("X"),
  }, {
    where: {
      id,
    },
  });
};

// 文献列表
const list = async (offset: number, limit: number, filters: { grounding?: number, name?: string, category_id?: string }) => {
  const whereObj: any = {};
  // 条件判断
  for (const v in filters) {
    if (v === "name" && filters[v]) {
      whereObj[v] = {
        [Op.substring]: filters[v],
      };
    }
    if (v === "grounding" && filters[v]) {
      whereObj[v] = filters[v];
    }
    if (v === "category_id" && filters[v]) {
      whereObj[v] = filters[v];
    }
  }

  // 查询字典分类id
  const dictData: any = await dictSql.getTypeId(<string>filters['category_id']);
  // 查询
  const { count, rows } = await literature.findAndCountAll({
    attributes: ["id", "name", "author", "press", "introduce", "code", "category_id", "recommend", "grounding", "visit_num"],
    where: whereObj,
    offset,
    limit,
    include: [
      {
        attributes: ["id", "size", "type", "path"],
        model: File,
        // 多个关联外键同时查询
        all: true,
      },
      {
        attributes: ["type_id", "name"],
        model: Dict,
        as: "dict",
      },
    ],
  });
  return { count, rows, dictData };
};

// 更新首页推荐
const updateRecommend = async (id: string, recommend: number) => {
  await literature.update({
    recommend,
    updated_at: moment().format("X"),
  }, {
    where: {
      id,
    },
  });
  return clone(Constant.DEFAULT_SUCCESS);
};

// 是否上架
const updateGrounding = async (id: string, grounding: number) => {
  await literature.update({
    grounding,
    updated_at: moment().format("X"),
  }, {
    where: {
      id,
    },
  });
  return clone(Constant.DEFAULT_SUCCESS);
};

// 文献详情
const detail = async (id: string) => {
  const data = await literature.findOne({
    attributes: ["id", "name", "author", "press", "introduce", "code", "category_id", "created_at"],
    where: {
      id,
    },
    include: [
      {
        attributes: ["id", "size", "type", "path"],
        model: File,
        // 多个关联外键同时查询
        all: true,
      },
      {
        attributes: ["type_id", "name"],
        model: Dict,
        as: "dict",
      },
    ],
  });
  return {
    ...Constant.DEFAULT_SUCCESS,
    data,
  };
};

// 前台
// 前台文献列表
const frontList = async (offset: number, limit: number, id: string, filters: { name?: string }) => {
  const whereObj: any = {};
  for (const v in filters) {
    if (v === "name" && filters[v]) {
      whereObj[v] = {
        [Op.substring]: filters[v],
      };
    }
  }
  // 查询
  const { count, rows } = await literature.findAndCountAll({
    attributes: ["id", "name", "author", "press", "introduce", "code", "category_id", "visit_num"],
    where: {
      category_id: id,
      [Op.or]: [{ recommend: 1 }, { grounding: 1 }],
      ...whereObj
    },
    offset,
    limit,
    include: [
      {
        attributes: ["id", "size", "type", "path"],
        model: File,
        // 多个关联外键同时查询
        all: true,
      },
      {
        attributes: ["type_id", "name"],
        model: Dict,
        as: "dict",
      },
    ],
  });
  return { count, rows };
};

// 推荐的文献
const recommend = async (filters: any) => {
  const whereObj: any = {};

  // 条件判断
  for (const v in filters) {
    if (v === "name" && filters[v]) {
      whereObj[v] = {
        [Op.substring]: filters[v],
      };
    }
  }

  const data = await literature.findAll({
    attributes: ["name", "id", "introduce"],
    where: {
      recommend: 1,
      ...whereObj,
    },
    include: [
      {
        attributes: ["id", "size", "type", "path"],
        model: File,
        // 多个关联外键同时查询
        all: true,
      },
      {
        attributes: ["type_id", "name"],
        model: Dict,
        as: "dict",
      },
    ],
  });
  return {
    data,
    ...Constant.DEFAULT_SUCCESS,
  };
};

// 文献排名
const ranking = async () => {
  const data = await literature.findAndCountAll({
    attributes: ["id", "name", "visit_num"],
    offset: 0,
    limit: 7,
    order: [
      ['visit_num', 'DESC'],
    ],
  });
  return {
    data,
    ...Constant.DEFAULT_SUCCESS,
  };
};

export default {
  add,
  _delete,
  isLiteratureName,
  isLiterature,
  isFileId,
  update,
  list,
  updateRecommend,
  updateGrounding,
  detail,
  frontList,
  recommend,
  ranking
};